/**
 * datagrid - jQuery xui
 *
 * Licensed under the Apache v2
 *
 * Copyright 2015 xjb [ beymy.en@gmail.com ]
 *
 * 依赖
 *	 pagination
 */
(function($) {
    /**
     * 包裹<table>,返回{columns}
     */
    function wrapGrid(target) {
        var columns = getColumns($('thead', target));

        function getColumns(thead) {
            var columns = [];
            $('tr', thead).each(function() {
                var cols = [];
                $('th', this).each(function() {
                    var th = $(this);

                    var col = $.extend({
                        title: th.html()
                    }, $.parser.parseOptions(this, [
                        'align', 'width', {
                            rowspan: 'number',
                            colspan: 'number'
                        }
                    ]));

                    cols.push(col);
                });
                columns.push(cols);
            });

            return columns;
        }

        return {
            columns: columns
        };
    }
    /**
     *构建body
     */
    function buildBody(target, rows) {
        var opts = $.data(target, 'datagrid').options;
        var fields = getColumnFields(opts.columns);


        var body = [];
        for (var i = 0; i < opts.pageSize && i < rows.length; i++) {
            var row = rows[i];
            if (i % 2 && opts.striped) {
                body.push('<tr x-datagrid-row-index="' + i + '" class="info">');
            } else {
                body.push('<tr x-datagrid-row-index="' + i + '">');
            }

			var rownumber = i + 1;
            if (opts.pagination) {
                rownumber += (opts.pageNumber - 1) * opts.pageSize;
            }
            
            for (var j = 0; j < fields.length; j++) {
                var field = fields[j];
                var col = getColumnOption(opts.columns, field);
                if (col) {
                	if (col.rownumber) {
                        body.push('<td class="x-datagrid-cell-rownumber">');
                    } else if (col.checkbox) {
                        body.push('<td class="x-datagrid-cell-check">');
                    } else {
                    	body.push('<td field="' + field + '">');
                    }
					
					if (col.rownumber) {
                        body.push(rownumber);
                    } else if (col.checkbox) {
                        body.push('<input type="checkbox"/>');
                    } else if (col.formatter) {
                        body.push(col.formatter(row[field], row, i));
                    } else {
                        body.push(row[field]);
                    }
                    body.push('</td>');
                }
            }
            body.push('</tr>');
        }

        $('>tbody', target).html(body.join(''));
    }

    /**
     *构建pagination
     */
    function buildPagination(target) {
        var state = $.data(target, 'datagrid');
        var opts = state.options;

        if (opts.pagination) {
            var pager = $(opts.pagination);
            pager.pagination({
                pageNumber: opts.pageNumber,
                pageSize: opts.pageSize,
                onSelectPage: function(pageNum, pageSize) {
                    // 保存分页状态
                    opts.pageNumber = pageNum;
                    opts.pageSize = pageSize;
        
                    request(target); // 请求远程数据
                }
            });
        }
    }

    /**
     * 绑定事件
     */
    function bindEvents(target) {
        var opts = $.data(target, 'datagrid').options;
        var data = $.data(target, 'datagrid').data;
        //body事件
        $('>tbody>tr>td.x-datagrid-cell-check>input[type="checkbox"]', target).unbind('.datagrid').bind('click.datagrid', function(e) {
            e.stopPropagation();
        });

        $('>tbody>tr', target).unbind('.datagrid').bind('click.datagrid', function() {
            var index = $(this).attr('x-datagrid-row-index');
            if (!$(this).hasClass('success')) {
                selectRow(target, index);
            }

            if (opts.onClickRow) {
                opts.onClickRow.call(this, index, data.rows[index]);
            }
        });

        //header事件
        $('>thead>tr>th.x-datagrid-cell-check>input[type="checkbox"]', target).unbind('.datagrid').bind('click.datagrid', function() {
            if ($(this).prop('checked')) {
                $('>tbody>tr>td.x-datagrid-cell-check>input[type="checkbox"]', target).prop('checked', true);
            } else {
                $('>tbody>tr>td.x-datagrid-cell-check>input[type="checkbox"]', target).prop('checked', false);
            }
        });
    }

    /**
     * 根据field获取对应field的选项
     */
    function getColumnOption(columns, field) {
        if (columns) {
            for (var i = 0; i < columns.length; i++) {
                var cols = columns[i];
                for (var j = 0; j < cols.length; j++) {
                    var col = cols[j];
                    if (col.field == field) {
                        return col;
                    }
                }
            }
        }
        return null;
    }

    /**
     * 获取fields
     */
    function getColumnFields(columns) {
        if (columns.length == 0) return [];

        function getFields(ridx, cidx, count) {
            var fields = [];
            while (fields.length < count) {
                var col = columns[ridx][cidx];
                if (col.colspan && col.colspan > 1) {
                    var ff = getFields(ridx + 1, getSubColIndex(ridx, cidx), col.colspan);
                    fields = fields.concat(ff);
                } else if (col.field) {
                    fields.push(col.field);
                }
                cidx++;
            }

            return fields;
        }

        function getSubColIndex(ridx, cidx) {
            var index = 0;
            for (var i = 0; i < cidx; i++) {
                var colspan = columns[ridx][i].colspan || 1;
                if (colspan > 1) {
                    index += colspan;
                }
            }
            return index;
        }

        var fields = [];
        for (var i = 0; i < columns[0].length; i++) {
            var col = columns[0][i];
            if (col.colspan && col.colspan > 1) {
                var ff = getFields(1, getSubColIndex(0, i), col.colspan);
                fields = fields.concat(ff);
            } else if (col.field) {
                fields.push(col.field);
            }
        }

        return fields;
    }

    /**
     * 获取colspan
     */
    function getColumnColspan(columns) {
        var column = columns[0];
        var colspan = 0;
        for (var i = 0; i < column.length; i++) {
            colspan += (column[i].colspan || 1);
        }
        return colspan;
    }

    /**
     * 加载数据
     */
    function loadData(target, data) {
        var state = $.data(target, 'datagrid');
        var opts = state.options;
        
        //数组数据处理
        if ($.isArray(data)) {
            data = {
                rows: data,
                total: data.length
            }
        } else {
            data.total = parseInt(data.total); //防止total是字符串
        }
        buildBody(target, data.rows);
        state.data = data;

		if(opts.pagination) {
	        $(opts.pagination).pagination({
	            total: data.total
	        });
    	}
        bindEvents(target);
    }

    /**
     * 获取checked记录
     */
    function getCheckedRows(target) {
        var state = $.data(target, 'datagrid');
        var data = state.data;

        var rows = [];
        $('>tbody>tr>td.x-datagrid-cell-check>input[type="checkbox"]:checked', target).parent().parent().each(function() {
            var index = parseInt($(this).attr('x-datagrid-row-index'));
            if (data.rows[index]) {
                rows.push(data.rows[index]);
            }
        });
        return rows;
    };

    /**
     * 获取selected记录
     */
    function getSelectedRows(target) {
        var state = $.data(target, 'datagrid');
        var data = state.data;

        var rows = [];
        $('>tbody>tr.success', target).each(function() {
            var index = parseInt($(this).attr('x-datagrid-row-index'));
            if (data.rows[index]) {
                rows.push(data.rows[index]);
            }
        });
        return rows;
    }

    /**
     * 清除全部选中记录
     */
    function clearSelections(target) {
        $('>tbody>tr.success', target).removeClass('success');
        $('>tbody>tr>td.x-datagrid-cell-check>input[type="checkbox"]', target).prop('checked', false);
    }

    /**
     * 根据索引选中记录,索引从这0开始
     */
    function selectRow(target, index) {
        var opts = $.data(target, 'datagrid').options;
        var data = $.data(target, 'datagrid').data;

        var tr = $('>tbody>tr[x-datagrid-row-index="' + index + '"]', target);
        clearSelections(target);
        tr.addClass('success');

        opts.onSelect.call(target, index, data.rows[index]);
    }

    /**
     * 请求远程数据
     */
    function request(target) {
        var state = $.data(target, 'datagrid');
        var opts = state.options;
        var grid = state.grid;

        if (!opts.url) {
            return false;
        }

        var param = $.extend({}, opts.queryParams);
        if (opts.pagination) {
            $.extend(param, {
                page: opts.pageNumber,
                rows: opts.pageSize
            });
        }

        $.ajax({
            type: opts.method,
            url: opts.url,
            data: param,
            dataType: 'json',
            success: function(data) {
                loadData(target, data);
                if (opts.onLoadSuccess) {
                    opts.onLoadSuccess.apply(this, arguments);
                }
            }
        });
    }

    $.fn.datagrid = function(options, param) {
        if (typeof options == 'string') {
            return $.fn.datagrid.methods[options](this, param);
        }

        options = options || {};

        return this.each(function() {
            var state = $.data(this, 'datagrid');
            var opts;
            if (state) {
                opts = $.extend(state.options, options);
            } else {
                opts = $.extend({}, $.fn.datagrid.defaults, $.fn.datagrid.parseOptions(this), options);

                var wrapResult = wrapGrid(this);
                if (!opts.columns) {
                    opts.columns = wrapResult.columns;
                }
                $.data(this, 'datagrid', {
                    options: opts,
                    data: {
                        total: 0,
                        rows: []
                    }
                });
            }

            buildPagination(this);

            if (opts.data) {
                loadData(this, opts.data);
            }

            if (opts.url) {
                request(this);
            }

            bindEvents(this);
        });
    };

    $.fn.datagrid.methods = {
        options: function(jq) {
            return $.data(jq[0], 'datagrid').options;
        },
        reload: function(jq) {
            return jq.each(function() {
                request(this);
            });
        },
        loadData: function(jq, param) {
            return jq.each(function() {
                loadData(this, param);
            });
        },
        getData: function(jq) {
            return $.data(jq[0], "datagrid").data;
        },
        getChecked: function(jq) {
            return getCheckedRows(jq[0]);
        },
        getSelected: function(jq) {
            var rows = getSelectedRows(jq[0]);
            return rows.length > 0 ? rows[0] : null;
        },
        clearSelections: function(jq) {
            return jq.each(function() {
                clearSelections(this);
            });
        },
        selectRow: function(jq, param) {
            return jq.each(function() {
                selectRow(this, param);
            });
        }
    };

    $.fn.datagrid.parseOptions = function(target) {
        return $.extend({}, $.parser.parseOptions(target, [
            'width', 'height', 'title'
        ]));
    };

    $.fn.datagrid.defaults = {
        title: '',
        iconCls: null,
        border: true,
        width: 'auto',
        height: 'auto',
        columns: null,
        striped: false, //条纹
        method: 'post',
        url: null,
        loadMsg: '正在处理，请稍待。。。',
        pagination: null,
        pageNumber: 1,
        pageSize: 10,
        queryParams: {},

        onLoadSuccess: function() {},
        onClickRow: function(rowIndex, rowData) {},
        onSelect: function(rowIndex, rowData) {}
    };
})(jQuery);
